/********************************************************
* ttt.js:
* Contains all code related to AI tic tac toe games and
* some code for PvP.
*********************************************************/

var playerPiece = "";	//Keep track of player piece
var inProgress = false;	//Tracker variable for game started
var pTurn = false;	//Tracker variable for player's turn
var pieceSet = false;	//Ensure a piece selected before started
var difficulty = "E";	//Game difficulty; E: Easy 	H: Hard
var aiPiece = "";	//Keep track of ai piece
var state = ""	//Keep track of state


//@TODO Pressing back button will stop the current game. Warn the user.

/* Initializes cookies for AI games */
function initAIPlay(){
	setCookie("wins", 0);	//Sets win cookie to 0
	setCookie("losses", 0);	//Sets loss cookie to 0
}

/* Resets the game to a zero state. Empty cells, etc. */
function resetGame(){
	if(!pieceSet){
			alert("Please select a piece.");
	}else{	//Check to see if they really want to start a new game
		var ok = true;
		if(inProgress){
			ok = confirm("Really start a new game?");
		}

		if(ok){	//Resets current game if active
			setBoard("NNNNNNNNN");
			resetDivBG();
			inProgress = true;
			if(playerPiece == "X")	//X Always goes first
				pTurn = true;
			else
				requestMove();
	
			setStatus("New game. Good luck!");
		}
	}
}

/* Takes a string (E or H) and displays the board html file */
function selectAI(s){
	difficulty = s;
	replacePage('info.htm', 'side');
}

/* Takes a string s (X or O) and sets the player piece to that */
function selectPiece(s){
	if(!inProgress){	//Can't select piece while playing
		playerPiece = s;
		if(s=="X"){	//Set pieces and images
			var xbtn = document.getElementById('xbtn');
			xbtn.src = "imgs/x_btn_sel.png";	//This and below toggles images
			document.getElementById('obtn').src = "imgs/o_btn.png";
			aiPiece = "O";
		}else{	//Same as above but reverse
			var obtn = document.getElementById('obtn');
			obtn.src = "imgs/o_btn_sel.png";
			document.getElementById('xbtn').src = "imgs/x_btn.png";
			aiPiece = "X";
		}
	}
	pieceSet = true;
	setStatus("Press 'New Game'");
}

/*Resets the piece images*/
function resetPiecePics(){
	document.getElementById('xbtn').src = "imgs/x_btn.png";
	document.getElementById('obtn').src = "imgs/o_btn.png";
}

/* XMLHttpRequest to servlet */
function requestMove(){
	var req = new XMLHttpRequest();
	var curBoard = getBoard(); //Gets current board

	//Sends a string to the servlet in form of [board][E/H][X/O]
	req.open("get", "servlet/ai_move/"+curBoard+difficulty+aiPiece, true);
	req.onreadystatechange = function(){
		if ( req.readyState == 4) {
	    	receiveMove( req )
		}		
	}
    req.send( null );
}

/* Acts on response from servlet */
function receiveMove(req){
	var d = req.responseXML.documentElement; //Get XML response
	var resps = d.textContent.split(";");	//Response string in form of [board];[state] 
	var board = resps[0];
	state = resps[1];
	setBoard(board);	//Update div board
	checkGameState(state);	//Check the state
}

/*Checks the games current state (IN_PROGRESS, X_WON, O_WON, DRAW)*/
function checkGameState(state){
	if(state == "IN_PROGRESS"){	//Game's still going
		pTurn = true;
		setStatus("Player turn...");
	}else{	//End condition met
		inProgress = false;
		if(state == "X_WON"){
			setOnWin("X");	//what happens when x wins
		}else if(state == "O_WON"){
			setOnWin("O");	//what happens when o wins
		}else if(state == "DRAW"){
			setOnWin("D"); //Draw
		}
	} 
}

/* Poorly named function that performs actions based on the end condition */
function setOnWin(p){
	inProgress = false;
	if(p == playerPiece){	//Player won
		setStatus("Player Wins!");
		setCookie("wins", parseInt(getCookie("wins"))+1); //Update cookie
	}else if(p == aiPiece){	//AI won
		setStatus("AI Wins...");
		setCookie("losses", parseInt(getCookie("losses"))+1);
	}else{
		setStatus("Draw.");
	}
	highlightWin(p);	//Highlights the win
	updateScores();	//Updates the on-screen scores
	
	var dpop = document.getElementById("popUpDiv");	//Pops up a div for playagain
	popup('popUpDiv');
}

/* When "YES" is pressed on the Play Again? pop up */
function playAgain(){
	popup('popUpDiv');	//Hides the popup
	var temp = playerPiece;	//Swaps X and O pieces
	playerPiece = aiPiece;
	aiPiece = temp;
	selectPiece(playerPiece);
	resetGame();
}

/* Returns the board as a 9 character string where X is X, O is O, and N is blank */
function getBoard(){
	var cells = document.getElementsByClassName('square');	//Get divs in board
	var boardString = "";	//Final representation
	for(var i = 0; i < cells.length; i++){
		var val = cells[i].innerHTML;
		if(val != "")
			boardString += val;
		else	//Empty div means "N"
			boardString += 'N';
	}
	return boardString;
}

/* Sets the divs to the passed-in board */
function setBoard(newBoard){
	var cells = document.getElementsByClassName('square');	//Get divs in board
	for(var i = 0; i < cells.length; i++){
		var val = newBoard[i];
		if(val == "N")
			cells[i].innerHTML = "";
		else
			cells[i].innerHTML = val;
	}
}

/* Called by each div in the board. Sets its innerHTML to that piece. */
/* row,col is the x,y positon of the div in the board */
function setXO(row, col){
	if(isPvP){	//If this is a PVP match, forward to that function.
				//Keeps compatibility with single board.htm file.
		pvp_setXO(row, col);
	}else{
		if(!inProgress){ //Make sure game is started.
			//alert("No game in progress! Please start a new game.");
		}else{
			if(!pTurn){	//Only allow the player to place after AI goes
				alert("Please wait your turn!");
			}else{	
				var sqr = document.getElementById(row+","+col); //Get the div clicked
				if(sqr.innerHTML == ""){	//Make sure it's blank
					sqr.innerHTML = playerPiece;	//Set the piece
					pTurn = false	//No longer player turn
					setStatus("Waiting for AI...");
					requestMove();	//Send request to servlet
				}
			}
		}
	}
}

/* Sets text s inside the status div in the info in side div */
function setStatus(s){
	var d = document.getElementById('status');
	d.innerHTML = s;
}

/* Figures out which positions caused a win. Forwards to a highlighter function. */
/* c is the character that caused the win */
function highlightWin(c){
	var b = getBoard(); //Board
	var winningString = ""; //Tracking var for win position

	//Possible winning conditions (8 possible for normal ttt)
	var w = ["111000000",
			"000111000",
			"000000111",
			"100100100",
			"010010010",
			"001001001",
			"100010001",
			"001010100"];

	for(var j = 0; j < w.length; j++){ //For each possible win string
		var count = 0;
		for(var k = 0; k < 9; k++){	//For each position in the string
			if(w[j][k] == "1"){	//If it's a 1 => required position
				if(b[k] == c){	//If it's equal to the char of interest
					count++;	//We've scored once.
					if(count == 3){	//Score 3 times, winner winner chicken dinner
						k = 10;	//Hack to escape the inner loop.
						winningString = w[j];	//Keep track of winner.
						j = 10;	//Hack to escape outer loop
					}
				}
			}
		}
	}		//It's like a waterfall of end curly braces...

	highlightDivs(winningString, c);	//Let's highlight 
}

/* s is the binary string of winning positions */
/* c is the character that caused the win */
/* Anywhere in s there's a 1, we highlight. */
function highlightDivs(s, c){
	var color = '';
	if (c==playerPiece || c==myPiece)	//If it's playerPiece in AI
										//or "myPiece" in PvP, highlight green
		color = 'rgb(0, 153, 0)';	//this is green
	else	//Else, player lost, so highlight red
		color = 'rgb(153, 0, 0)';	//this is red

	var d = document.getElementsByClassName('square');	//Get divs in board...
	for(var i = 0; i < 9; i++){
		if(s[i] == "1"){	//Wherever there's a one, color it
			d[i].style.backgroundColor = color;
		}
	}
}

/* Simply resets sthe background color of divs */
function resetDivBG(){
	var d = document.getElementsByClassName('square');
	for(var i = 0; i < 9; i++)
		d[i].style.backgroundColor = '';
}

/* Sets a cookie of name = value */
function setCookie(name, value){
	value = escape(value);
	document.cookie = name + "=" + value;
}

/*Returns the value of cookieName */
function getCookie(cookieName){
	//Creates a regular expression that:
		//Starts with ; or space
		//Followed by cookieName
		//Followed by an =
		//And cannot contain a space or ;
	var re = new RegExp('[; ]'+cookieName+'=([^\\s;]*)');
	var sMatch = (' '+document.cookie).match(re); //Match it to cookies in document
	if (cookieName && sMatch)	//Make sure not null
		return unescape(sMatch[1]);	//Unescape (remove slashes) and return
	return '';	//Otherwise it wasn't found
}

/* Checks win and loss cookies and creates the if not found*/
function checkCookies(){
	var wins = getCookie("wins");
	var losses = getCookie("losses");
	if(wins == "")
		setCookie("wins", 0);
	if(losses == "")
		setCookie("losses", 0);
}

/* Updates the scores on screen */		
function updateScores(){
	var winsP = document.getElementById("wins");
	var lossesP = document.getElementById("losses");

	winsP.innerHTML = "Wins: " + getCookie("wins");
	lossesP.innerHTML = "Losses: " + getCookie("losses");
}

/* What occurs when back is pressed in AI Info screen */
function infoBackPressed(){
	var ok = true;
	if(inProgress){	//Back is pressed while in progress, warn the user
		ok = confirm("Warning, this will end your current game. Continue?");
	}
	if(ok){	//Kill the game. Kill the piece. Reset the side page.
		inProgress = false;
		pieceSet = false;
		pTurn = false;
		setBoard("NNNNNNNNN");
		resetDivBG();
		replacePage('opponent.htm', 'side');
	}
}
